﻿using System;
using System.Collections;
using System.Reflection;
using Microsoft.Office.Interop.Excel;

namespace XD.Office
{
    public partial class XlsTemplateExporter
    {
        /// <summary>
        /// 导出数据卡
        /// </summary>
        /// <param name="entity">数据实体</param>
        /// <param name="xlsFile">导出文件</param>
        /// <returns></returns>
        public bool ExportDataCard(object entity)
        {
            bool ok = false;

            Worksheet sheet = null;
            object missing = Type.Missing;
            try
            {

                string tmpFile = _param.TemplateFile;
                //打卡Excel
                OpenWorkbook();
                sheet = GetWorksheet(_book);

                Replace(entity, sheet);
                ok = true;
            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
            }

            return ok;
        }

        /// <summary>
        /// 导出数据表
        /// </summary>
        /// <param name="entityList">实体列表</param>
        /// <param name="xlsFile"></param>
        /// <returns></returns>
        public bool ExportData(IEnumerable entityList)
        {
            //获取枚举对象
            IEnumerator enumerator = entityList.GetEnumerator();
            //判断是否空列表
            if (!enumerator.MoveNext())
            {
                return false;
            }

            bool ok = false;

            Worksheet sheet = null;
            object missing = Type.Missing;
            try
            {

                string tmpFile = _param.TemplateFile;
                //打卡Excel
                OpenWorkbook();
                sheet = GetWorksheet(_book);

                enumerator.Reset();
                enumerator.MoveNext();
                object firstEntity = enumerator.Current;
                Type tt = firstEntity.GetType();
                //获取列名称
                string[] columns = GetColumns(enumerator.Current, sheet);

                //写入数据
                int startrow = _param.StartRow;
                int startcol = _param.StartColumn;
                int row = 0;
                
                enumerator.Reset();
                while (enumerator.MoveNext() && row <= _param.MaxRows)
                {
                    object entity = enumerator.Current;
                    for (int col = 0; col < columns.Length; col++)
                    {
                        object v = tt.InvokeMember(columns[col], BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public, null, entity, null);
                        string value = "";
                        if (v != DBNull.Value)
                        {
                            value = Convert.ToString(v);
                        }
                        sheet.Cells[startrow + row, startcol + col] = value;
                    }

                    row++;
                }
                
                ok = true;
            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
            }

            return ok;
        }

        /// <summary>
        /// 导出数据表
        /// </summary>
        /// <param name="cardEntity">数据卡的实体</param>
        /// <param name="entityList">实体列表</param>
        /// <param name="xlsFile"></param>
        /// <returns></returns>
        public bool ExportCombo(object cardEntity, IEnumerable entityList)
        {
            //获取枚举对象
            IEnumerator enumerator = entityList.GetEnumerator();
            //判断是否空列表
            if (!enumerator.MoveNext())
            {
                return false;
            }

            bool ok = false;

            Worksheet sheet = null;
            object missing = Type.Missing;
            try
            {

                string tmpFile = _param.TemplateFile;
                //打卡Excel
                OpenWorkbook();
                sheet = GetWorksheet(_book);

                enumerator.Reset();
                enumerator.MoveNext();
                object firstEntity = enumerator.Current;
                Type tt = firstEntity.GetType();
                //获取列名称
                string[] columns = GetColumns(firstEntity, sheet);

                //替换方式输出数据
                Replace(cardEntity, sheet);

                //写入数据
                int startrow = _param.StartRow;
                int startcol = _param.StartColumn;
                int row = 0;

                enumerator.Reset();
                while (enumerator.MoveNext() && row <= _param.MaxRows)
                {
                    object entity = enumerator.Current;
                    for (int col = 0; col < columns.Length; col++)
                    {
                        object v = tt.InvokeMember(columns[col], BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public, null, entity, null);
                        string value = "";
                        if (v != DBNull.Value)
                        {
                            value = Convert.ToString(v);
                        }
                        sheet.Cells[startrow + row, startcol + col] = value;
                    }

                    row++;
                }

                ok = true;
            }
            catch (Exception err)
            {
                Console.WriteLine(err.Message);
            }

            return ok;
        }

        /// <summary>
        /// 替换
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="sheet"></param>
        private void Replace(object entity, Worksheet sheet)
        {
            Type tt = entity.GetType();
            PropertyInfo[] proties = tt.GetProperties();
            object missing = Type.Missing;
            foreach (PropertyInfo pi in proties)
            {
                if (!pi.CanRead)
                    continue;
                object v = tt.InvokeMember(pi.Name, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public, null, entity, null);
                string value = "";
                if (v != DBNull.Value)
                {
                    value = Convert.ToString(v);
                }
                
                //查找字符串
                string oldStr = string.Format(_param.ReplaceRule, pi.Name.ToUpper());
                Range range = sheet.Cells.Find(oldStr, missing, missing, missing, missing, XlSearchDirection.xlNext, missing, missing, missing);
                if (range != null)
                {
                    sheet.Cells.Replace(oldStr, value, missing, missing, missing, missing, missing, missing);
                }
            }
        }

        /// <summary>
        /// 获取配置的字段
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="sheet"></param>
        /// <returns></returns>
        private string[] GetColumns(object entity, Worksheet sheet)
        {
            string[] columns = _param.Columns;
            if (columns == null)
            {
                Type tt = entity.GetType();
                PropertyInfo[] proties = tt.GetProperties();

                int index = 0;
                columns = new string[proties.Length];
                foreach (PropertyInfo pi in proties)
                {
                    if (!pi.CanRead)
                        continue;
                    columns[index] = pi.Name;
                    index++;
                }
                //在第一行创建列头
                for (int i = 0; i < columns.Length; i++)
                {
                    sheet.Cells[1, _param.StartColumn + i] = columns[i];
                }
            }
            return columns;
        }
    }

}
